﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NUnit.Framework;
using Core;
using Core.UIItems;
using Core.UIItems.ListBoxItems;
using Core.UIItems.WindowItems;
using System.Diagnostics;

namespace UITestSuite
{
    [TestFixture]
    public class OptionsDialogTests
    {
        #region Private Data
        private Application applicationUnderTest;
        private Window mainWindow;
        private TestParameters testParameters;
        private Button actionButton;
        private Window optionsDialogWindow;
        private CheckBox checkBox;
        private ComboBox comboBox;
        #endregion

        #region NUnit convenience methods 
 
        /// <summary>
        /// Before each test, get the test parameters and delete offline store
        /// </summary>
        [SetUp]
        public void Setup()
        {
            testParameters = new TestParameters();
            UITestHelperClass.DeleteUserConfigFile();
            UITestHelperClass.DeleteOfflineStore(testParameters.StandardDataStoreFolderName, testParameters.CustomDataStoreFileName);
        }

        /// <summary>
        /// If the test fails, it might leave the app running so we check and 
        /// shut it down (if necessary)in the teardown 
        /// </summary>
        [TearDown]
        public void TearDown()
        {
            if (applicationUnderTest != null && applicationUnderTest.HasExited == false)
            {
                applicationUnderTest.Kill();
            }
        }
        #endregion

        #region NUnit Tests

        /// <summary>
        /// This test verifies that the default settings for all options are as expected. 
        /// </summary>
        [Test]
        public void VerifyDefaultOptions()
        {
            StartAppAndStartOptionsDialog();

            // Verify Defaults
            comboBox = optionsDialogWindow.Get<ComboBox>("AutoExpireDaysComboBox");
            Assert.IsNotNull(comboBox);
            Assert.IsFalse(comboBox.Enabled);

            checkBox = optionsDialogWindow.Get<CheckBox>("PostDownloadPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsFalse(checkBox.Enabled);

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsTrue(checkBox.Checked);

            comboBox = optionsDialogWindow.Get<ComboBox>("SynchSettingsComboBox");
            Assert.IsNotNull(comboBox);
            Assert.IsTrue(comboBox.Enabled);
            Assert.IsTrue(comboBox.SelectedItemText == "Every 5 minutes");

            optionsDialogWindow.Close();
            if (mainWindow != null) mainWindow.Close();
        }


        /// <summary>
        /// This test verifies that settings chosen by the user persist across invocations of the 
        /// Options Dialog within a single execution of the Forums Client and across multiple 
        /// executions of the Forums Client
        /// </summary>
        [Test]
        public void UserOptionsPersist()
        {
            StartAppAndStartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);

            Assert.IsTrue(checkBox.Checked);
            checkBox.Click();
            Assert.IsFalse(checkBox.Checked);

            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Restart Options Dialog and verify that the choice persists
            StartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsFalse(checkBox.Checked);

            // Exit the windows and app
            optionsDialogWindow.Close();
            if (mainWindow != null)
            {
                mainWindow.Close();
            }

            // Restart the Client and verify that the choice persists across runs
            StartAppAndStartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);

            Assert.IsFalse(checkBox.Checked);

            // Change the settings
            checkBox.Click();
            Assert.IsTrue(checkBox.Checked);

            comboBox = optionsDialogWindow.Get<ComboBox>("SynchSettingsComboBox");
            Assert.IsNotNull(comboBox);
            Assert.IsTrue(comboBox.Enabled);
            comboBox.Select("Every 30 minutes");
            Assert.IsTrue(comboBox.SelectedItemText.Equals("Every 30 minutes"));
            System.Threading.Thread.Sleep(5000);

            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Exit the app
            mainWindow.Close();

            // Restart the Client and verify that the choice persists across runs
            StartAppAndStartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsTrue(checkBox.Checked);
            comboBox = optionsDialogWindow.Get<ComboBox>("SynchSettingsComboBox");
            Assert.IsNotNull(comboBox);
            Assert.IsTrue(comboBox.SelectedItemText.Equals("Every 30 minutes"));

            // Exit the windows and app
            optionsDialogWindow.Close();
            mainWindow.Close();
        }

        /// <summary>
        /// This test verifies that the user can select various time intervals for 
        /// automatic synchronization and turn automatic synchronization on and off.
        /// </summary>
        [Test]
        public void SetAutomaticSynchronizationTimeInterval()
        {
            StartAppAndStartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);

            // Turn off automatic synchronization
            checkBox.Click();
            Assert.IsFalse(checkBox.Checked);

            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            StartOptionsDialog();

            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsFalse(checkBox.Checked);

            // Turn on automatic synchronization
            checkBox.Click();
            Assert.IsTrue(checkBox.Checked);

            actionButton = optionsDialogWindow.Get<Button>("Save");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            string[] intervalOptionStrings = { "Every 10 minutes", "Every 15 minutes", "Every 30 minutes", "Every 60 minutes", "Every 5 minutes", "Once Per Day" };
            string lastOption = "Every 5 minutes";

            // Select time intervals in the order shown in the initialization of intervalOptionStrings
            foreach (string currentOption in intervalOptionStrings)
            {
                StartOptionsDialog();
                checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
                Assert.IsNotNull(checkBox);
                Assert.IsTrue(checkBox.Checked);
                comboBox = optionsDialogWindow.Get<ComboBox>("SynchSettingsComboBox");
                Assert.IsNotNull(comboBox);
                Assert.IsTrue(comboBox.SelectedItemText.Equals(lastOption));
                lastOption = currentOption;
                comboBox.Select(currentOption);

                actionButton = optionsDialogWindow.Get<Button>("Save");
                Assert.IsNotNull(actionButton);
                actionButton.Click();
            }

            // Check that the last option was set
            StartOptionsDialog();
            checkBox = optionsDialogWindow.Get<CheckBox>("AutoSynchPreferenceCheckBox");
            Assert.IsNotNull(checkBox);
            Assert.IsTrue(checkBox.Checked);
            comboBox = optionsDialogWindow.Get<ComboBox>("SynchSettingsComboBox");
            Assert.IsNotNull(comboBox);
            Assert.IsTrue(comboBox.SelectedItemText.Equals(lastOption));

            // Exit the windows and app
            optionsDialogWindow.Close();
            mainWindow.Close();
        }

        /// <summary>
        /// This test cycles through the themes 
        /// </summary>
        [Test]
        public void ExerciseThemeButton()
        {
            // Start the App and get the main window
            applicationUnderTest = Application.Launch("ForumsClient.exe");
            mainWindow = (Window)applicationUnderTest.GetWindow(UITestSuiteStringResourceFile.MicrosoftForumsClientBuildName, Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(mainWindow);

            UITestHelperClass.CancelLogon(mainWindow);

            // Find and click the Theme button
            actionButton = mainWindow.Get<Button>("ThemeButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();
            System.Threading.Thread.Sleep(1000);
            actionButton.Click();
            System.Threading.Thread.Sleep(1000);
            actionButton.Click();
            System.Threading.Thread.Sleep(1000);
        }

        #endregion


        #region Private Methods

        /// <summary>
        /// Starts the app, Cancels the Logon dialog, and 
        /// starts the Options Dialog
        /// </summary>
        private void StartAppAndStartOptionsDialog()
        {
            // Start the App and get the main window
            applicationUnderTest = Application.Launch("ForumsClient.exe");
            mainWindow = (Window)applicationUnderTest.GetWindow(UITestSuiteStringResourceFile.MicrosoftForumsClientBuildName, Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(mainWindow);

            UITestHelperClass.CancelLogon(mainWindow);

            StartOptionsDialog();
        }

        /// <summary>
        /// Starts Options Dialog from the main window
        /// </summary>
        private void StartOptionsDialog()
        {
            // Find and click the Options button
            actionButton = mainWindow.Get<Button>("OptionsButton");
            Assert.IsNotNull(actionButton);
            actionButton.Click();

            // Find the OptionsDialog Window
            optionsDialogWindow = mainWindow.ModalWindow("OptionsDialog", Core.Factory.InitializeOption.NoCache);
            Assert.IsNotNull(optionsDialogWindow);
        }
        #endregion

    }
}
